package org.hackystat.devcathlon.engine.user;

import java.util.List;
import static org.junit.Assert.*;

import org.hackystat.devcathlon.engine.profile.Profile;
import org.hackystat.devcathlon.engine.profile.ProfileManager;
import org.junit.Test;

/**
 * Test UserManager class.
 * 
 * @author Anthony Du
 *
 */
public class TestUserManager {

  private static final String firstName = "Anthony";
  private static final String lastName = "Du";
  private static final String email = "anthony@gmail.com";
  private static final String password = email;

  /**
   * Test adding/loading/deleting of a User.
   */
  @Test
  public void testUserManager() {
    User user = UserManager.getInstance().addUser(firstName, lastName, email, password);
    User selectedUser = UserManager.getInstance().getUser(email);
    // test to see if the user added is the same as the user selected.
    assertEquals("should be the same", selectedUser, user);
    // clean up
    UserManager.getInstance().deleteUser(email);
    // test to see if the user deleted is truly gone.
    assertNull("should be null", UserManager.getInstance().getUser(email));
  }

  /**
   * Test getUsers.
   */
  @Test
  public void testGetUsers() {
    // Test to see if the list of users is empty.
    List<?> usersList = UserManager.getInstance().getUsers();
    assertTrue("users list should be empty", usersList.isEmpty());
    User user1 = UserManager.getInstance().addUser(firstName, lastName, email, password);
    User user2 = UserManager.getInstance().addUser(firstName, lastName, email + ".net", password);
    // Test to see if only two users reside in the query.
    usersList = UserManager.getInstance().getUsers();
    int numUsers = usersList.size();
    assertEquals("should have 2 users", 2, numUsers);
    // Test if the users were the original ones added.
    User selectedUser = UserManager.getInstance().getUser(email);
    assertEquals("should be user 1", user1, selectedUser);
    selectedUser = UserManager.getInstance().getUser(email + ".net");
    assertEquals("should be user 2", user2, selectedUser);
    UserManager.getInstance().deleteUser(email);
    UserManager.getInstance().deleteUser(email + ".net");
    usersList = UserManager.getInstance().getUsers();
    assertTrue("users list should be empty", usersList.isEmpty());
  }
 
  /**
   * Test user update.
   */
  @Test
  public void testUpdateUser() {
    User user = UserManager.getInstance().addUser(firstName, lastName, email, password);
    // update user
    User updatedUser = user;
    String otherEmail = "someother@email.com";
    updatedUser.setEmail(otherEmail);
    UserManager.getInstance().updateUser(updatedUser);
    // test to see if they are the same record
    assertSame("should be the same user", updatedUser, user);
    // test to see if record has in fact changed
    assertNotSame("should not be the same email", email, updatedUser.getEmail());
  }
  
  /**
   * Test user profile association.
   */
  @Test
  public void testUserProfile() {
    String gender = "male";
    String location = "hawaii";
    String contact = "808";
    // create a user
    User user = UserManager.getInstance().addUser(firstName, lastName, email, password);
    // create a profile
    Profile profile = ProfileManager.getInstance().addProfile(user, gender, location, 
        contact, "", "");
    // associate profile and user
    user.setProfile(profile);
    // test to see if the user profile is the same as the associated
    assertEquals("should be the same profile", profile, user.getProfile());
    // test to see if the profile user is the same as the associated
    assertEquals("should be the same user", user, profile.getUser());
    // test retrieving information from user profile (by association)
    assertEquals("should be the same gender", gender, user.getProfile().getGender());
    assertEquals("should be the same location", location, user.getProfile().getLocation());
    assertEquals("should be the same contact", contact, user.getProfile().getContact());
    // test delete user (should also delete profile).
    UserManager.getInstance().deleteUser(email);
    assertNull("user should be null", UserManager.getInstance().getUser(email));
    assertNull("profile should be null", ProfileManager.getInstance().getProfile(email));
  }
}
